#pragma once

#include "NetworkMessage.h"
#include <map>
#include <memory>
#include <mutex>
#include <queue>
#include <functional>
#include <vector>
#include <atomic>

namespace SeanNetwork {

// 前向声明
template<typename T>
class LockFreeQueue;

// 消息确认回调函数类型
using MessageAckCallback = std::function<void(uint32_t messageId, bool success)>;

// 消息重传策略接口
class IResendStrategy {
public:
    virtual ~IResendStrategy() = default;
    
    // 计算下一次重传间隔（毫秒）
    virtual uint32_t GetNextResendInterval(uint32_t resendCount) = 0;
    
    // 获取最大重传次数
    virtual uint32_t GetMaxResendCount() = 0;
};

// TCP指数退避重传策略
class TcpResendStrategy : public IResendStrategy {
public:
    TcpResendStrategy(uint32_t initialInterval = 1000, uint32_t maxInterval = 30000, uint32_t maxResendCount = 5);
    
    uint32_t GetNextResendInterval(uint32_t resendCount) override;
    uint32_t GetMaxResendCount() override;
    
private:
    uint32_t m_InitialInterval;  // 初始重传间隔（毫秒）
    uint32_t m_MaxInterval;      // 最大重传间隔（毫秒）
    uint32_t m_MaxResendCount;   // 最大重传次数
};

// KCP快速重传策略
class KcpResendStrategy : public IResendStrategy {
public:
    KcpResendStrategy(uint32_t fixedInterval = 100, uint32_t maxResendCount = 10);
    
    uint32_t GetNextResendInterval(uint32_t resendCount) override;
    uint32_t GetMaxResendCount() override;
    
private:
    uint32_t m_FixedInterval;   // 固定重传间隔（毫秒）
    uint32_t m_MaxResendCount;  // 最大重传次数
};

/**
 * @brief 无锁消息队列节点
 */
template<typename T>
struct LockFreeNode {
    T data;
    std::atomic<LockFreeNode<T>*> next;
    
    LockFreeNode() : next(nullptr) {}
    explicit LockFreeNode(const T& val) : data(val), next(nullptr) {}
    explicit LockFreeNode(T&& val) : data(std::move(val)), next(nullptr) {}
};

/**
 * @brief 无锁队列实现
 * 
 * 基于单生产者多消费者(SPMC)模型的无锁队列
 */
template<typename T>
class LockFreeQueue {
public:
    LockFreeQueue() {
        LockFreeNode<T>* dummy = new LockFreeNode<T>();
        m_Head.store(dummy);
        m_Tail.store(dummy);
    }
    
    ~LockFreeQueue() {
        // 释放队列中的所有节点
        T dummy;
        while (Dequeue(dummy)) {}
        
        // 释放哑节点
        LockFreeNode<T>* head = m_Head.load();
        delete head;
    }
    
    // 禁止复制和移动
    LockFreeQueue(const LockFreeQueue&) = delete;
    LockFreeQueue& operator=(const LockFreeQueue&) = delete;
    LockFreeQueue(LockFreeQueue&&) = delete;
    LockFreeQueue& operator=(LockFreeQueue&&) = delete;
    
    /**
     * @brief 入队操作
     * @param item 要入队的元素
     */
    void Enqueue(const T& item) {
        LockFreeNode<T>* newNode = new LockFreeNode<T>(item);
        
        // 获取当前尾节点并将新节点放在其后
        LockFreeNode<T>* oldTail = m_Tail.load(std::memory_order_relaxed);
        oldTail->next.store(newNode, std::memory_order_release);
        
        // 更新尾指针
        m_Tail.store(newNode, std::memory_order_release);
    }
    
    /**
     * @brief 入队操作（移动版本）
     * @param item 要入队的元素
     */
    void Enqueue(T&& item) {
        LockFreeNode<T>* newNode = new LockFreeNode<T>(std::move(item));
        
        // 获取当前尾节点并将新节点放在其后
        LockFreeNode<T>* oldTail = m_Tail.load(std::memory_order_relaxed);
        oldTail->next.store(newNode, std::memory_order_release);
        
        // 更新尾指针
        m_Tail.store(newNode, std::memory_order_release);
    }
    
    /**
     * @brief 出队操作
     * @param result 用于存储出队元素的引用
     * @return 如果队列非空且出队成功，返回true；否则返回false
     */
    bool Dequeue(T& result) {
        LockFreeNode<T>* oldHead = m_Head.load(std::memory_order_relaxed);
        LockFreeNode<T>* next = nullptr;
        
        do {
            next = oldHead->next.load(std::memory_order_acquire);
            if (!next) {
                return false;  // 队列为空
            }
        } while (!m_Head.compare_exchange_weak(oldHead, next, std::memory_order_release));
        
        // 获取数据
        result = std::move(next->data);
        
        // 释放旧的头节点
        delete oldHead;
        
        return true;
    }
    
    /**
     * @brief 检查队列是否为空
     * @return 队列为空返回true，否则返回false
     */
    bool IsEmpty() const {
        return m_Head.load(std::memory_order_relaxed)->next.load(std::memory_order_relaxed) == nullptr;
    }
    
private:
    std::atomic<LockFreeNode<T>*> m_Head;
    std::atomic<LockFreeNode<T>*> m_Tail;
};

// 消息池类，管理发送中的消息和重传机制
class MessagePool {
public:
    MessagePool();
    ~MessagePool();
    
    /**
     * @brief 初始化消息池
     * @return 是否成功初始化
     */
    bool Initialize();
    
    /**
     * @brief 更新消息池，处理超时消息
     */
    void Update();
    
    // 添加消息到发送池
    bool AddMessage(std::shared_ptr<NetworkMessage> message, ChannelType channel);
    
    // 确认消息已接收
    bool AcknowledgeMessage(uint32_t messageId, ChannelType channel);
    
    // 设置消息确认回调
    void SetAckCallback(MessageAckCallback callback);
    
    // 检查和处理超时消息，返回需要重传的消息列表
    std::vector<std::shared_ptr<NetworkMessage>> CheckTimeoutMessages();
    
    // 设置消息存活时间（毫秒）
    void SetMessageTimeToLive(uint64_t ttlMilliseconds);
    
    // 设置重传策略
    void SetResendStrategy(ChannelType channel, std::shared_ptr<IResendStrategy> strategy);
    
    // 获取待发送的优先消息，按优先级排序
    std::shared_ptr<NetworkMessage> GetNextPendingMessage();
    
    // 获取消息队列大小
    size_t GetPendingMessageCount() const;
    
    // 获取已发送未确认的消息数量
    size_t GetUnacknowledgedMessageCount(ChannelType channel) const;
    
    // 清空所有消息
    void Clear();
    
    /**
     * @brief 无锁方式添加发送消息
     * @param message 要发送的消息
     */
    void EnqueueOutgoingMessage(std::shared_ptr<NetworkMessage> message);
    
    /**
     * @brief 无锁方式获取下一个待发送消息
     * @param message 用于存储获取的消息
     * @return 如果有消息则返回true，否则返回false
     */
    bool DequeueOutgoingMessage(std::shared_ptr<NetworkMessage>& message);
    
private:
    struct MessageState {
        std::shared_ptr<NetworkMessage> Message;
        ChannelType Channel;
        uint64_t NextResendTime;   // 下次重传时间

		MessageState() {}
        
        MessageState(std::shared_ptr<NetworkMessage> msg, ChannelType ch)
            : Message(msg), Channel(ch), NextResendTime(0) {
        }
    };

    std::map<uint32_t, MessageState> m_PendingMessages;     // 待确认的消息，按消息ID索引
    std::map<uint8_t, std::queue<uint32_t>> m_PriorityQueues; // 按优先级组织的待发送消息队列
    std::mutex m_Mutex;
    uint64_t m_MessageTtl;                                 // 消息生存时间（毫秒）
    MessageAckCallback m_AckCallback;                       // 消息确认回调
    std::map<ChannelType, std::shared_ptr<IResendStrategy>> m_ResendStrategies; // 各通道的重传策略
    
    // 无锁队列，用于存储待发送的消息
    LockFreeQueue<std::shared_ptr<NetworkMessage>> m_OutgoingQueue;
    
    /* 功能：计算下一次重传时间
       参数：message-需要重传的消息，channel-传输通道
       返回：下次重传的时间点（毫秒时间戳） */
    uint64_t CalculateNextResendTime(const std::shared_ptr<NetworkMessage>& message, ChannelType channel);
    
    /* 功能：处理消息超时
       参数：messageId-超时的消息ID，channel-传输通道 */
    void HandleMessageTimeout(uint32_t messageId, ChannelType channel);
};

} // namespace SeanNetwork
